#include "gd32f4xx_gpio.h"
#include "gd32f4xx_rcu.h"
#include "gd32f4xx_usart.h"

void uart0_init()
{
    // 使能模块时钟
    rcu_periph_clock_enable(RCU_GPIOB);  // 使能 GPIOB 时钟
    rcu_periph_clock_enable(RCU_USART0); // 使能 USART0 时钟

    // 设置 USART0_TX USART0_RX 引脚功能
    gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_6); // USART0_TX: PB6 AF7
    gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_7); // USART0_RX: PB7 AF7

    // 设置 USART0_TX 引脚 上下拉模式 和 时钟频率
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);

    // 设置 USART0_RX 引脚 上下拉模式 和 时钟频率
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);

    // 复位 USART0
    usart_deinit(USART0);

    // USART0 参数设置
    usart_baudrate_set(USART0, 115200U); // 波特率
    usart_word_length_set(USART0, USART_WL_8BIT); // 数据位
    usart_parity_config(USART0, USART_PM_NONE); // 校验位
    usart_stop_bit_set(USART0, USART_STB_1BIT); // 停止位
    usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE); // 禁用 CTS
    usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE); // 禁用 RTS

    // 使能USART0接收发送
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);

    // 打开 USART0
    usart_enable(USART0);
}

#ifdef __GNUC__
int _write (int fd, char *buffer, int size)
{
    for (int i = 0; i < size; i++)
    {
        usart_data_transmit(USART0, buffer[i]);
        while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
    }
    return size;
}
#else
int fputc(int ch, FILE *f)
{
    usart_data_transmit(USART0, (uint8_t)ch);
    while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
    return ch;
}
#endif
